#include <gtest/gtest.h>

#include "MemoryDBTest.h"

class ReExecuteTest : public test::MemoryDBTest {
};


#include "helper/sqlite/IDB.h"
#include "helper/sqlite/Statement.h"


TEST_F(ReExecuteTest, withNoInput){
  std::error_code ec;
  auto && stmt_insert = db().createStatement("insert into tab1 values ('1111', 23);", ec); 
  ASSERT_TRUE(stmt_insert && !ec);
  auto && stmt_delete = db().createStatement("delete from tab1 where one = '1111';", ec);
  ASSERT_TRUE(stmt_delete && !ec);

  {
    //first 
    ASSERT_TRUE(stmt_insert->execute());
    ASSERT_TRUE(stmt_delete->execute());

    //second
    ASSERT_EQ(0, stmt_insert->reset().value());
    ASSERT_TRUE(stmt_insert->execute());

    ASSERT_EQ(0, stmt_delete->reset().value());
    ASSERT_TRUE(stmt_delete->execute());
  }

  {//for loop 

    for(int i = 0; i < 10; ++i){
      ASSERT_EQ(0, stmt_insert->reset().value());
      ASSERT_TRUE(stmt_insert->execute());

      ASSERT_EQ(0, stmt_delete->reset().value());
      ASSERT_TRUE(stmt_delete->execute());
    }

    for(int i =0; i < 10; ++i, stmt_insert->reset(), stmt_delete->reset()){
      ASSERT_TRUE(stmt_insert->execute());
      ASSERT_TRUE(stmt_delete->execute());
    }
  }
 } 
TEST_F(ReExecuteTest, withBind){

  std::error_code ec;
  auto && stmt_insert = db().createStatement("insert into tab1 values (?, 23);", ec); 
  ASSERT_TRUE(stmt_insert && !ec);

  auto && stmt_delete = db().createStatement("delete from tab1 where one = ?;", ec);
  ASSERT_TRUE(stmt_delete && !ec);
  

  {
    std::string  key = "1111";
    //first 
    ASSERT_EQ(0, stmt_insert->textBind(1, key).value());
    ASSERT_TRUE(stmt_insert->execute());

    ASSERT_EQ(0, stmt_delete->textBind(1, key).value());
    ASSERT_TRUE(stmt_delete->execute());

    key = "222l22222";
    //second : note othe order: reset -> clearBindings -> bind -> execute
    ASSERT_EQ(0, stmt_insert->reset().value());
    ASSERT_EQ(0, stmt_insert->clearBindings().value());
    ASSERT_EQ(0, stmt_insert->textBind(1, key).value());
    ASSERT_TRUE(stmt_insert->execute());

    ASSERT_EQ(0, stmt_delete->reset().value());
    ASSERT_EQ(0, stmt_delete->clearBindings().value());
    ASSERT_EQ(0, stmt_delete->textBind(1, key).value());
    ASSERT_TRUE(stmt_delete->execute());
  }

  {//for loop 
    std::string key;
    for(int i = 0 ;i < 10; ++i){
      key = std::to_string(i);
      ASSERT_EQ(0, stmt_insert->reset().value());
      ASSERT_EQ(0, stmt_insert->clearBindings().value());
      ASSERT_EQ(0, stmt_insert->textBind(1, key).value());
      ASSERT_TRUE(stmt_insert->execute());

      ASSERT_EQ(0, stmt_delete->reset().value());
      ASSERT_EQ(0, stmt_delete->clearBindings().value());
      ASSERT_EQ(0, stmt_delete->textBind(1, key).value());
      ASSERT_TRUE(stmt_delete->execute());
    }
  }
}
